using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using IWshRuntimeLibrary;
using System.Resources;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Collections;
using System.Threading;
using Microsoft.Win32;

namespace Notify2
{
    public partial class SetupForm : Form
    {
        internal static string setupPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "GmailNotifier2");
        internal static string notifierGroup = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Programs), "Gmail Notifier 2");

        public SetupForm()
        {
            InitializeComponent();
        }

        bool runWithoutInstall = false;

        public bool RunWithoutInstall
        {
            get { return runWithoutInstall; }
            set { runWithoutInstall = value; }
        }

        private void SetupForm_Load(object sender, EventArgs e)
        {
            //groupBox1.Top = -7;
            //groupBox1.Left = -5;
            //groupBox1.Width = this.Width + 10;
            //groupBox1.Height = groupBox1.Height + 30;

            if (Directory.Exists(SetupForm.setupPath))
            {
                setupPathTextbox.Text = string.Format(My.Resources.WillOverwriteFiles, " \"" + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "GmailNotifier2") + "\" ");
                setupPathTextbox.Text += "\r\n" + My.Resources.UserConfigLeftIntact;
            }
            else
                setupPathTextbox.Text = My.Resources.FilesWillBeCopied + "  \"" + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "GmailNotifier2") + "\"";
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void runNoInstallButton_Click(object sender, EventArgs e)
        {
            runWithoutInstall = true;
            this.Close();
        }

        void SetupIcon(string setupPath, string notifierGroup, string name, int icon, string deployText)
        {
            // Copy exe file to User Application Data Folder
            string iconPath;
            iconPath = Path.Combine(SetupForm.setupPath, name);
            if (!Directory.Exists(iconPath))
                Directory.CreateDirectory(iconPath);
            string file = Path.GetFileName(Application.ExecutablePath);
            string destFile = Path.Combine(iconPath, file);
            SetupUtils.Copy(Application.ExecutablePath, destFile);

            // Create Start Programs shortcut
            WshShellClass WshShell = new WshShellClass();
            string iconLink = Path.Combine(notifierGroup, "GmailNotifier2 - " + name + ".lnk");
            SetupUtils.DeleteFile(iconLink);

            IWshRuntimeLibrary.IWshShortcut MyShortcut = null;
            try
            {
                MyShortcut = (IWshRuntimeLibrary.IWshShortcut)WshShell.CreateShortcut(iconLink);
                MyShortcut.TargetPath = destFile;
                MyShortcut.Description = "Gmail Notifier 2 - " + name + " icon";
                MyShortcut.IconLocation = MyShortcut.TargetPath + "," + icon;
                MyShortcut.Save();
            }
            catch (Exception ex)
            {
                if (MyShortcut != null)
                {
                    ex.Data.Add("TargetPath", MyShortcut.TargetPath);
                    ex.Data.Add("FullName", MyShortcut.FullName);
                }
                throw;
            }
            // Write config file to set specific color/instance
            deployText = deployText.Replace("$(ColorProperty)", name.ToLower());
            StreamWriter deployfile = System.IO.File.CreateText(Path.Combine(iconPath, file + ".config"));
            deployfile.Write(deployText);
            deployfile.Close();
        }

        private void installButton_Click(object sender, EventArgs e)
        {
            try
            {
                // Create Folder to hold all instances of GmailNotifier2
                if (!Directory.Exists(SetupForm.setupPath))
                    Directory.CreateDirectory(SetupForm.setupPath);
                else
                {
                    ShutdownNotifierProcesses();
                }

                // Program Group
                SetupUtils.DeleteDirectory(notifierGroup);
                Directory.CreateDirectory(notifierGroup);

                // Contents of the config file, to be customized for each instance
                Assembly assembly = Assembly.GetExecutingAssembly();
                StreamReader deployconfig = new StreamReader(assembly.GetManifestResourceStream("Notify2.deploy.config"));
                string deployText = deployconfig.ReadToEnd();

                // Create the uninstaller
                string uninstall = Path.Combine(SetupForm.setupPath, "uninstall.exe");
                SetupUtils.Copy(Application.ExecutablePath, uninstall);
                RegistryKey key;
                using (key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall", true))
                {
                    using (RegistryKey key2 = key.CreateSubKey("Gmail Notifier 2"))
                    {
                        key2.SetValue("DisplayIcon", uninstall);
                        key2.SetValue("DisplayName", "Gmail Notifier 2");
                        key2.SetValue("DisplayVersion", Application.ProductVersion);
                        key2.SetValue("InstallDate", DateTime.Now.ToString("yyyyMMdd"));
                        key2.SetValue("InstallLocation", SetupForm.setupPath);
                        key2.SetValue("NoModify", 1);
                        key2.SetValue("NoRepair", 1);
                        key2.SetValue("Publisher", "sometmes@gmail.com");
                        key2.SetValue("UninstallString", uninstall);
                        key2.SetValue("Version", Application.ProductVersion);
                    }
                }

                // Create Exe and program group icon for each instance
                SetupIcon(SetupForm.setupPath, notifierGroup, "Blue", 1, deployText);
                SetupIcon(SetupForm.setupPath, notifierGroup, "Green", 2, deployText);
                SetupIcon(SetupForm.setupPath, notifierGroup, "Pink", 3, deployText);

                // If user asked for it, run a new fresh instance of Gmail Notifier2
                if (runIconCheckBox.Checked)
                {
                    string tag = iconDropDown.Tag as string;
                    string iconPath = Path.Combine(SetupForm.setupPath, tag);
                    string file = Path.GetFileName(Application.ExecutablePath);
                    string destFile = Path.Combine(iconPath, file);
                    Process.Start(destFile);
                }
                Application.Exit();
            }
            catch (Exception ex)
            {
                Exception baseex = ex.GetBaseException();
                string msg = baseex.Message;
                foreach (DictionaryEntry de in baseex.Data)
                    msg += "\r\n" + de.Key + ": " + de.Value;
                MessageBox.Show(msg);
            }
        }

        private void Test()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Stream res = assembly.GetManifestResourceStream("Notify2.cleaner.exe");
            byte[] resbytes = new byte[res.Length];
            res.Read(resbytes, 0, (int)res.Length);
            string cleanerPath = Path.Combine(SetupForm.setupPath, "cleaner.exe");
            FileStream cleaner = new FileStream(
                cleanerPath, 
                FileMode.Create, 
                FileAccess.Write, 
                FileShare.Delete, 
                8, 
                FileOptions.None | FileOptions.DeleteOnClose
                );
            cleaner.Write(resbytes, 0, (int)res.Length);
            FileStream dummy = new FileStream(cleanerPath, FileMode.Open, FileAccess.Read, 
                FileShare.Read |FileShare.Write | FileShare.Delete);
            cleaner.Close();
            Process.Start(cleanerPath);
            dummy.Close();
            Application.Exit();
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        private static int WM_CLOSE = 0x10;
        //private static int WM_QUIT = 0x12;

        internal static void ShutdownNotifierProcesses()
        {
            IntPtr wnd;
            bool someClosed = false;
            wnd = FindWindow((string)null, "NotifierTrayHiddenForm");
            while (wnd != IntPtr.Zero)
            {
                SendMessage(wnd, WM_CLOSE, 0, 0);
                someClosed = true;
                wnd = FindWindow((string)null, "NotifierTrayHiddenForm");
            }
            if (someClosed) //Thread.Sleep(2000);
            {
                int bottom = 0;
                if (Path.GetFileName(Application.ExecutablePath).ToLower() == "gmailnotifier2")
                    bottom = 1;
                while (Process.GetProcessesByName("GmailNotifier2").Length > bottom)
                    Thread.Sleep(200);
            }
        }

        private void iconDropDown_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            iconDropDown.Image = e.ClickedItem.Image;
            iconDropDown.Tag = e.ClickedItem.Tag;
        }
    }
}